package pers.xiaojun.boot.module.system.service.capthca;

import cn.hutool.captcha.AbstractCaptcha;
import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.CircleCaptcha;
import cn.hutool.captcha.ICaptcha;
import cn.hutool.captcha.generator.CodeGenerator;
import cn.hutool.captcha.generator.MathGenerator;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import pers.xiaojun.boot.common.config.properties.CaptchaProperties;
import pers.xiaojun.boot.common.exception.BusinessException;
import pers.xiaojun.boot.common.pojo.ImageCaptcha;
import pers.xiaojun.boot.module.system.constants.BusinessCodeConstants;
import pers.xiaojun.boot.module.system.controller.captcha.vo.CaptchaRespVO;
import pers.xiaojun.boot.module.system.dao.redis.CaptchaRedisDAO;

import java.time.LocalDateTime;

import static pers.xiaojun.boot.module.system.constants.BusinessCodeConstants.AUTH_CAPTCHA_BED_CREDENTIALS;
import static pers.xiaojun.boot.module.system.constants.BusinessCodeConstants.AUTH_CAPTCHA_NOT_EXISTS;

/**
 * 验证码服务层实现
 *
 * @author xiaojun
 * @since 2025-10-06
 */
@Service
@RequiredArgsConstructor
public class CaptchaServiceImpl implements CaptchaService {

    private final CaptchaRedisDAO captchaRedisDAO;

    private final ImageCaptcha imageCaptcha;
    private final CodeGenerator codeGenerator;
    private final CaptchaProperties captchaProperties;

    @Override
    public void removeCaptcha(String captchaKey) {
        captchaRedisDAO.deleteByKey(captchaKey);
    }

    @Override
    public CaptchaRespVO getCaptcha() {
        // 创建默认验证码
        AbstractCaptcha captcha = imageCaptcha.createDefaultCaptcha();
        // 构建验证码响应对象
        CaptchaRespVO captchaRespVO = CaptchaRespVO.builder()
                .captchaKey(IdUtil.simpleUUID())
                .captchaBase64(captcha.getImageBase64Data())
                .expireTime(LocalDateTimeUtil.toEpochMilli(LocalDateTime.now().plusSeconds(captchaProperties.getExpiresIn())) / 1000)
                .build();

        captchaRedisDAO.save(captchaRespVO.getCaptchaKey(), captcha.getCode());

        return captchaRespVO;
    }

    @Override
    public void verify(String captchaKey, String captchaValue) {
        // 获取 Redis 中的验证码
        String redisValue = captchaRedisDAO.getValueByKey(captchaKey);
        // 为空说明不存在
        if (StrUtil.isEmpty(redisValue)) {
            throw new BusinessException(AUTH_CAPTCHA_NOT_EXISTS);
        }
        boolean verify = codeGenerator.verify(redisValue, captchaValue);
        if (!verify) {
            throw new BusinessException(AUTH_CAPTCHA_BED_CREDENTIALS);
        }
    }
}
